package server;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.XMLDecoder;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.rmi.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import common.ServerInterface;
import common.Utilities;

public class IMServerTray {

	private static final Image STOP_ICON = Utilities.createImage("resource/stop.png","stop icon");
	private static final Image START_ICON = Utilities.createImage("resource/start.png","start icon");
	private static TrayIcon trayIcon;
	private static ServerConfiguration config;
	private static MenuItem startItem;
	private static MenuItem stopItem;
	private static String homeDir;
	
	public static void main(String[] args){
		if(new File("lib/IM-server.jar").exists()){
			homeDir = new File("").getAbsolutePath();
		}
		else{
			try {
				File jarFile = new File(IMServerTray.class.getProtectionDomain().getCodeSource().getLocation().toURI());
				homeDir = jarFile.getParent();
			} catch (URISyntaxException e) {
				e.printStackTrace();
			}
		}
		if(args.length>1&&args[0].equals("stop")){
			ServerInterface server = null;
			homeDir = args[1];
			loadConfiguration();
			if(config!=null)
				server = getServer();
    		if(server != null){
    			try {
					server.shutDown(config.getKey());
				} catch (RemoteException e1) {
					e1.printStackTrace();
				}
    		}
    		return;
		}
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
            	loadConfiguration();
                createAndShowGUI();
            }
        });
	}
	
	private static void loadConfiguration(){
		File serverConf = new File(homeDir+"/conf/server.xml");
		try{
			XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream(serverConf)));
			config = (ServerConfiguration) decoder.readObject();
			decoder.close();
		} catch (FileNotFoundException e){
			
		}

	}
	
    private static void createAndShowGUI() {
        //Check the SystemTray support
        if (!SystemTray.isSupported()) {
            System.out.println("SystemTray is not supported");
            return;
        }
        final PopupMenu popup = new PopupMenu();
		ServerInterface server = null;
        if(config!=null)
        	server = getServer();
        Image icon = START_ICON;
        if(server == null) icon = STOP_ICON;
        trayIcon =
                new TrayIcon(icon);
        final SystemTray tray = SystemTray.getSystemTray();
        trayIcon.setImageAutoSize(true);
        trayIcon.setToolTip("IM Server Monitor");
        
        // Create a popup menu components
        MenuItem aboutItem = new MenuItem("About");
        startItem = new MenuItem("Start");
        stopItem = new MenuItem("Stop");
        MenuItem exitItem = new MenuItem("Exit");
        
        if(server == null){
        	stopItem.setEnabled(false);
        	startItem.setEnabled(true);
        }
        else{
        	startItem.setEnabled(false);
        	stopItem.setEnabled(true);
        }
        //Add components to popup menu
        popup.add(aboutItem);
        popup.addSeparator();
        popup.add(startItem);
        popup.add(stopItem);
        popup.addSeparator();
        popup.add(exitItem);

        trayIcon.setPopupMenu(popup);
        
        try {
            tray.add(trayIcon);
        } catch (AWTException e) {
            System.out.println("TrayIcon could not be added.");
            return;
        }
        aboutItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(null,
                        "RMI IM Server By Zexu Xu");
            }
        });
        
        exitItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                tray.remove(trayIcon);
                System.exit(0);
            }
        });
        
        startItem.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
    			ServerInterface server = null;
        		if(config!=null)
        			server = getServer();
        		if(server == null){
        			try {
        				String javaHome = System.getenv("JAVA_HOME");
        				ArrayList<String> cmds = new ArrayList<String>();
        				if(javaHome!=null &&!javaHome.equals(""))
        					cmds.add(javaHome+"/bin/java");
        				else cmds.add("java");
        				cmds.add("-classpath");
        				cmds.add(homeDir+"/lib/IM-server.jar");
        				cmds.add("-Dim.server.home="+homeDir);
        				cmds.add("server.IMServer");
        				cmds.add(homeDir+"/lib/IM-server.jar");
        				new ProcessBuilder(cmds).start();
    	    			trayIcon.setImage(START_ICON);
    	    			stopItem.setEnabled(true);
    	    			startItem.setEnabled(false);
					} catch (IOException e1) {
						e1.printStackTrace();
					}
        		}
        	}
        });

        stopItem.addActionListener(new ActionListener() {
        	public void actionPerformed(ActionEvent e) {
				loadConfiguration();
				ServerInterface server = null;
				if(config!=null)
					server = getServer();
        		if(server != null){
        			try {
						server.shutDown(config.getKey());
					} catch (RemoteException e1) {
						e1.printStackTrace();
					}
        			trayIcon.setImage(STOP_ICON);
        			stopItem.setEnabled(false);
        			startItem.setEnabled(true);
        		}
        	}
        });
        
        new Thread(new StatusUpdater()).start();
}

	private static ServerInterface getServer(){
		try {
			return (ServerInterface) Naming.lookup("rmi://localhost:"
					+ config.getServerPort() + "/" + config.getServerServiceName());
		} catch (MalformedURLException e) {
		} catch (RemoteException e) {
		} catch (NotBoundException e) {
		}
		return null;
	}
	
	private static class StatusUpdater implements Runnable{

		@Override
		public void run() {
			while(!Thread.interrupted()){
				try {
					Thread.sleep(15000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if(config == null) loadConfiguration();
				if(getServer() == null){
					startItem.setEnabled(true);
					stopItem.setEnabled(false);
					trayIcon.setImage(STOP_ICON);
				} else{
					startItem.setEnabled(false);
					stopItem.setEnabled(true);
					trayIcon.setImage(START_ICON);
				}
			}
		}
		
	}
}
